home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 301-325 / disk_313 / uucp / uucp1.lzh / src / lib / alias.c next >
C/C++ Source or Header  |  1990-01-10  |  4KB  |  222 lines

  1.  
  2. /*
  3.  *  ALIAS.C
  4.  *
  5.  *  (C) Copyright 1989-1990 by Matthew Dillon,  All Rights Reserved.
  6.  *
  7.  *  Interpret UULIB:Aliases file.  To save space we do not load
  8.  *  the entire file, just sections on demand.
  9.  *
  10.  *  #    = comment
  11.  *  id: name [, name...]
  12.  *
  13.  *  name is a user name, path, or |filter, or quoted name.  Example,
  14.  *  "|more" or "|rnews"
  15.  */
  16.  
  17. #include <proto/all.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <fcntl.h>
  21. #include <time.h>
  22.  
  23. #include "log.h"
  24.  
  25. #define HASHSIZE    256
  26. #define HASHMASK    (HASHSIZE-1)
  27.  
  28. #define HF_TERM     0x01    /*    terminator name     */
  29. #define HF_ALIAS    0x02    /*    alias            */
  30. #define HF_LOADED   0x04    /*    def loaded        */
  31.  
  32. typedef struct Hash {
  33.     struct Hash *Next;
  34.     short   NumAlias;    /*  # of aliases    */
  35.     short   Flags;
  36.     char    *Name;    /*  aliased user name    */
  37.     union {
  38.     struct Hash    **Alias;    /*  list of aliases       */
  39.     long    Offset;     /*    offset into file    */
  40.     } u;
  41. } Hash;
  42.  
  43. static Hash    *HashTab[HASHSIZE];
  44. static char    Tmp[256];
  45.  
  46. void
  47. LoadAliases()
  48. {
  49.     FILE *fi = fopen("UULIB:Aliases", "r");
  50.     short i;
  51.     short j;
  52.     short k;
  53.     short line = 0;
  54.     long newoffset = 0;
  55.     long offset;
  56.     Hash *h;
  57.     char *buf = Tmp;
  58.  
  59.     if (fi == NULL) {
  60.     ulog(-1, "Can't open UULIB:Aliases");
  61.     return;
  62.     }
  63.     while (fgets(buf, 256, fi)) {
  64.     offset = newoffset;
  65.     newoffset = ftell(fi);
  66.     ++line;
  67.     for (i = 0; buf[i] == ' ' || buf[i] == 9; ++i);
  68.     if (buf[i] == '#' || buf[i] == '\n')
  69.         continue;
  70.     for (j = i; buf[j] && buf[j] != ':'; ++j);
  71.     if (buf[j] == 0) {
  72.         ulog(-1, "No Colon UULIB:Aliases line %d", line);
  73.         continue;
  74.     }
  75.     buf[j] = 0;
  76.  
  77.     k = HashFunc(buf + i);
  78.     h = malloc(sizeof(Hash));
  79.     h->Next = HashTab[k];
  80.     h->NumAlias = 0;
  81.     h->Flags = HF_ALIAS;
  82.     h->Name = malloc(strlen(buf+i) + 1);
  83.     h->u.Offset = offset + j + 1;
  84.     strcpy(h->Name, buf + i);
  85.  
  86.     HashTab[k] = h;
  87.     }
  88.     fclose(fi);
  89. }
  90.  
  91. static
  92. Hash *
  93. FindHashObject(name)
  94. char *name;
  95. {
  96.     short k = HashFunc(name);
  97.     Hash *h;
  98.  
  99.     for (h = HashTab[k]; h; h = h->Next) {
  100.     if (strcmp(name, h->Name) == 0)
  101.         return(h);
  102.     }
  103.     return(NULL);
  104. }
  105.  
  106. static
  107. void
  108. LoadHashObject(hash)
  109. Hash *hash;
  110. {
  111.     FILE *fi = fopen("UULIB:Aliases", "r");
  112.     char *buf = Tmp;
  113.     short i, j;
  114.     short c;
  115.     short numalloc = 4;
  116.     Hash **hv = malloc(sizeof(Hash *) * 4);
  117.     Hash *h;
  118.  
  119.     if (fi == NULL) {
  120.     ulog(-1, "Can't open UULIB:Aliases");
  121.     return;
  122.     }
  123.  
  124.     hash->Flags |= HF_LOADED;
  125.     fseek(fi, hash->u.Offset, 0);
  126.     while (fgets(buf, 256, fi)) {
  127.     i = 0;
  128.     c = 'x';
  129.  
  130.     for (;;) {
  131.         while (buf[i] == ' ' || buf[i] == 9)
  132.         ++i;
  133.         if (buf[i] == 0 || buf[i] == '\n')
  134.         break;
  135.  
  136.         for (j = i; buf[j] != '\n' && buf[j] != ' ' && buf[j] != 9 && buf[j] != ','; ++j) {
  137.         if (buf[j] == '\"') {
  138.             i = j + 1;
  139.             for (++j; buf[j] != '\n' && buf[j] != '\"'; ++j);
  140.             break;
  141.         }
  142.         }
  143.         c = buf[j];
  144.         buf[j] = 0;
  145.  
  146.         if ((h = FindHashObject(buf + i)) == NULL) {
  147.         short k = HashFunc(buf + i);
  148.  
  149.         h = malloc(sizeof(Hash));
  150.         h->Next = HashTab[k];
  151.         h->NumAlias = 0;
  152.         h->Flags = HF_TERM;
  153.         h->Name = malloc(strlen(buf + i) + 1);
  154.         h->u.Alias = NULL;
  155.         strcpy(h->Name, buf + i);
  156.  
  157.         HashTab[k] = h;
  158.         }
  159.  
  160.         if (hash->NumAlias == numalloc) {
  161.         Hash **hvo = hv;
  162.         short add = 4;
  163.  
  164.         hv = malloc(sizeof(Hash *) * (numalloc + add));
  165.         movmem((char *)hvo, (char *)hv, sizeof(Hash *) * numalloc);
  166.         numalloc += add;
  167.         }
  168.         hv[hash->NumAlias++] = h;
  169.  
  170.         i = j + 1;
  171.         if (c == '\"')
  172.         c = buf[i++];
  173.         if (c == '\n' || c == 0)
  174.         i = j;
  175.     }
  176.     if (c != ',')
  177.         break;
  178.     }
  179.     hash->u.Alias = hv;
  180. }
  181.  
  182. void
  183. UserAliasList(user, callback)
  184. char *user;
  185. void (*callback)();
  186. {
  187.     short i;
  188.     Hash *hash = FindHashObject(user);
  189.     static short stack;
  190.  
  191.     if (++stack == 32) {
  192.     ulog(-1, "UULIB:Aliases recursion near user %s", user);
  193.     --stack;
  194.     return;
  195.     }
  196.  
  197.     if (hash && (hash->Flags & HF_TERM) == 0) {
  198.     if ((hash->Flags & HF_LOADED) == 0)
  199.         LoadHashObject(hash);
  200.     for (i = 0; i < hash->NumAlias; ++i) {
  201.         Hash *h = hash->u.Alias[i];
  202.         UserAliasList(h->Name, callback);
  203.     }
  204.     } else {
  205.     (*callback)(user);
  206.     }
  207.     --stack;
  208. }
  209.  
  210. static int
  211. HashFunc(str)
  212. char *str;
  213. {
  214.     unsigned long v = 0x14FBA5C3;
  215.     while (*str) {
  216.     v = (v << 5) ^ (*str & 0x1F) ^ (v >> 27);
  217.     ++str;
  218.     }
  219.     return((int)(v & HASHMASK));
  220. }
  221.  
  222.